{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# AI第五周作业——基于物品的协同过滤"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "import math"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>user</th>\n",
       "      <th>song</th>\n",
       "      <th>play_count</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOADQPP12A67020C82</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOAFTRR12AF72A8D4D</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOANQFY12AB0183239</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOAYATB12A6701FD50</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>d6589314c0a9bcbca4fee0c93b14bc402363afea</td>\n",
       "      <td>SOBOAFP12A8C131F36</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                                       user                song  play_count\n",
       "0  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOADQPP12A67020C82           5\n",
       "1  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOAFTRR12AF72A8D4D           1\n",
       "2  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOANQFY12AB0183239           1\n",
       "3  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOAYATB12A6701FD50           1\n",
       "4  d6589314c0a9bcbca4fee0c93b14bc402363afea  SOBOAFP12A8C131F36           5"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 读入数据\n",
    "df_music = pd.read_csv('triplet_dataset_sub_5000_song.csv') \n",
    "df_music.head()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>play_count</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>count</th>\n",
       "      <td>3.712888e+06</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>mean</th>\n",
       "      <td>2.369724e+00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>std</th>\n",
       "      <td>1.619127e+00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>min</th>\n",
       "      <td>1.000000e+00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>25%</th>\n",
       "      <td>1.000000e+00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>50%</th>\n",
       "      <td>2.000000e+00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>75%</th>\n",
       "      <td>4.000000e+00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>max</th>\n",
       "      <td>5.000000e+00</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "         play_count\n",
       "count  3.712888e+06\n",
       "mean   2.369724e+00\n",
       "std    1.619127e+00\n",
       "min    1.000000e+00\n",
       "25%    1.000000e+00\n",
       "50%    2.000000e+00\n",
       "75%    4.000000e+00\n",
       "max    5.000000e+00"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_music.describe()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 将表格转换成稀疏矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(99612, 4001)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from scipy.sparse import coo_matrix\n",
    "\n",
    "small_set = df_music\n",
    "user_codes = small_set.user.drop_duplicates().reset_index()\n",
    "song_codes = small_set.song.drop_duplicates().reset_index()\n",
    "user_codes.rename(columns={'index':'user_index'}, inplace=True)\n",
    "song_codes.rename(columns={'index':'song_index'}, inplace=True)\n",
    "song_codes['song_index_value'] = list(song_codes.index)\n",
    "user_codes['user_index_value'] = list(user_codes.index)\n",
    "small_set = pd.merge(small_set,song_codes,how='left')\n",
    "small_set = pd.merge(small_set,user_codes,how='left')\n",
    "mat_candidate = small_set[['user_index_value','song_index_value','play_count']]\n",
    "\n",
    "data_array = mat_candidate.play_count.values\n",
    "row_array = mat_candidate.user_index_value.values\n",
    "col_array = mat_candidate.song_index_value.values\n",
    "\n",
    "data_sparse = coo_matrix((data_array, (row_array, col_array)),dtype=float)\n",
    "data_sparse.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_sparse_arr = data_sparse.toarray()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 找出打分最多前4首歌曲"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "import copy\n",
    "\n",
    "def findMostRateSong(arr, songNum, commonNum):\n",
    "\n",
    "    songRate = [0 for i in range(songNum)]\n",
    "    \n",
    "    for i in range(len(arr)):\n",
    "        #for j in range(len(arr[0])):\n",
    "        for j in range(songNum):\n",
    "            if arr[i][j] > 0.1:\n",
    "                songRate[j] += 1\n",
    "    \n",
    "    songRateSort= copy.copy(songRate)\n",
    "    songRateSort.sort(reverse = True)                 \n",
    "    #print(songRate)\n",
    "    #print(songRateSort)\n",
    "                       \n",
    "    MostRateSongCount = [songRateSort[i] for i in range(commonNum)]\n",
    "                       \n",
    "    MostRateSongID = []\n",
    "   \n",
    "    for i in range(len(songRate)):\n",
    "        for j in range(len(MostRateSongCount)):\n",
    "            if songRate[i] == MostRateSongCount[j]:\n",
    "                MostRateSongID.append(i)           \n",
    "                   \n",
    "    return MostRateSongID, MostRateSongCount     "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "def findMostSongUserID(arr, MostRateSongID):\n",
    "    \n",
    "    UserRateID = []\n",
    "    SongRate = []\n",
    "    \n",
    "    for i in range(len(arr)):\n",
    "        isRate = True\n",
    "        uSongRate = []\n",
    "        for j in range(len(MostRateSongID)):\n",
    "            if arr[i][j] < 0.1:\n",
    "                isRate = False\n",
    "            else:\n",
    "                uSongRate.append(arr[i][j])\n",
    "        if isRate:\n",
    "            SongRate.append(uSongRate)\n",
    "            UserRateID.append(i)\n",
    "            \n",
    "    return UserRateID, SongRate"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "def UserFilter(UserASongRate, UserBSongRate):\n",
    "    \n",
    "    UserARateSum = 0\n",
    "    for i in range(len(UserASongRate) - 1):\n",
    "        UserARateSum += UserASongRate[i]    \n",
    "    UserAAverage = UserARateSum / (len(UserASongRate) - 1)\n",
    "    #print('UserAAverage:', UserAAverage)\n",
    "    \n",
    "    UserBRateSum = 0\n",
    "    for i in range(len(UserBSongRate) - 1):\n",
    "        UserBRateSum += UserBSongRate[i]\n",
    "    UserBAverage = UserBRateSum / (len(UserBSongRate) - 1)\n",
    "    #print('UserBAverage:', UserBAverage)\n",
    "    \n",
    "    sum = 0\n",
    "    for i in range(len(UserASongRate) - 1):\n",
    "        sum += (UserASongRate[i] - UserAAverage) * (UserBSongRate[i] - UserBAverage)\n",
    "    numerator = sum\n",
    "    #print('numerator:', numerator)\n",
    "    \n",
    "    sum = 0\n",
    "    for i in range(len(UserASongRate) - 1):\n",
    "        sum += pow((UserASongRate[i] - UserAAverage), 2)\n",
    "    leftPart = np.sqrt(sum)    \n",
    "    \n",
    "    sum = 0\n",
    "    for i in range(len(UserBSongRate) - 1):\n",
    "        sum += pow((UserBSongRate[i] - UserBAverage), 2)\n",
    "    rightPart = np.sqrt(sum)\n",
    "    \n",
    "    denominator = leftPart * rightPart\n",
    "    #print('denominator:', denominator)\n",
    "    \n",
    "    sim = numerator / denominator\n",
    "    \n",
    "    return sim"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 105,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MostRateSongID: [29, 680, 707, 1044]\n",
      "MostRateSongCount: [18626, 17635, 15138, 14945]\n"
     ]
    }
   ],
   "source": [
    "MostRateSongID , MostRateSongCount = findMostRateSong(data_sparse_arr, data_sparse_arr.shape[1], 4)\n",
    "print('MostRateSongID:', MostRateSongID)\n",
    "print('MostRateSongCount:', MostRateSongCount)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 100,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "UserRateID: [0, 650, 815, 898, 1519, 2446, 2722, 3285, 3740, 4068, 4607, 4827, 5119, 5434, 5676, 5721, 6162, 6199, 6264, 6509, 6662, 6900, 7119, 7401, 7451, 7798, 8080, 8443, 8473, 8855, 8916, 9424, 9505, 10195, 10540, 10649, 10894, 11035, 11846, 11925, 12068, 12957, 13578, 13684, 14053, 14330, 14600, 15209, 16205, 16441, 16471, 16527, 16694, 17071, 17216, 17368, 17535, 17803, 18865, 19191, 19443, 20244, 20718, 21109, 22210, 22222, 22416, 22494, 23027, 23051, 23293, 23325, 23561, 23564, 23653, 23930, 24263, 24812, 24990, 25006, 25056, 25060, 25206, 25350, 25834, 26075, 26093, 26110, 26131, 26275, 26402, 26795, 27076, 27213, 27986, 28443, 28763, 29046, 29239, 29900, 29925, 30288, 31637, 31675, 31741, 31792, 32255, 32514, 32557, 32961, 33377, 33478, 33770, 34196, 34255, 34258, 34842, 35129, 35377, 35500, 35867, 35993, 36016, 36314, 36588, 36786, 36969, 37266, 38110, 38242, 39040, 39320, 40381, 40604, 40764, 41010, 41439, 41548, 42129, 42133, 43015, 43574, 44619, 44708, 44840, 44869, 45315, 45325, 45424, 45785, 45852, 48884, 49563, 49726, 50469, 51463, 51596, 51762, 52129, 52316, 52591, 53242, 53590, 53730, 53846, 54237, 54719, 54822, 54825, 54914, 54962, 55245, 55455, 55877, 56720, 56950, 57184, 57236, 57551, 57841, 58009, 58059, 58081, 58099, 58369, 58402, 58744, 58845, 58937, 59166, 59310, 60206, 60226, 60408, 60432, 60541, 61033, 61339, 61502, 61610, 62029, 62217, 63223, 63240, 63474, 63709, 64104, 64366, 64918, 64952, 65483, 65587, 65675, 65737, 65803, 65827, 66218, 66481, 66594, 66615, 66680, 67052, 67414, 67533, 67887, 68290, 68834, 69029, 69221, 69609, 69824, 69842, 69866, 70514, 70736, 70847, 70941, 71517, 72072, 72373, 72406, 73295, 73517, 73616, 73851, 74402, 74465, 74842, 74959, 74965, 75292, 75326, 76352, 76588, 76596, 76617, 76683, 77301, 77405, 78154, 79008, 79022, 79923, 80531, 80576, 80683, 80914, 81186, 81679, 81972, 82243, 82577, 82611, 82655, 82783, 82786, 82905, 83271, 83311, 83383, 84076, 84498, 84952, 85254, 85512, 85810, 86308, 86921, 86969, 87043, 87395, 88020, 88089, 88104, 88695, 89124, 89718, 90106, 90269, 91392, 91461, 91660, 91778, 91912, 93154, 93276, 93604, 94594, 95418, 95518, 96271, 96554, 96834, 96951, 97229, 97332, 97582, 97769, 97888, 97907, 98816, 99155, 99492, 99610]\n",
      "SongRate: [[5.0, 1.0, 1.0], [1.0, 3.0, 3.0], [5.0, 1.0, 1.0], [1.0, 2.0, 3.0], [2.0, 2.0, 1.0], [1.0, 1.0, 1.0], [2.0, 2.0, 1.0], [3.0, 1.0, 1.0], [1.0, 1.0, 3.0], [2.0, 1.0, 1.0], [1.0, 1.0, 2.0], [1.0, 4.0, 3.0], [1.0, 1.0, 2.0], [1.0, 1.0, 1.0], [3.0, 5.0, 5.0], [4.0, 1.0, 1.0], [2.0, 2.0, 4.0], [5.0, 4.0, 5.0], [1.0, 1.0, 1.0], [1.0, 1.0, 5.0], [5.0, 4.0, 2.0], [2.0, 1.0, 3.0], [1.0, 1.0, 2.0], [1.0, 5.0, 2.0], [5.0, 2.0, 5.0], [2.0, 5.0, 5.0], [4.0, 1.0, 1.0], [2.0, 1.0, 1.0], [5.0, 5.0, 5.0], [5.0, 2.0, 1.0], [3.0, 2.0, 5.0], [5.0, 3.0, 2.0], [1.0, 1.0, 1.0], [2.0, 1.0, 1.0], [1.0, 1.0, 1.0], [2.0, 1.0, 3.0], [4.0, 3.0, 5.0], [2.0, 1.0, 1.0], [1.0, 5.0, 4.0], [1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [1.0, 2.0, 1.0], [4.0, 5.0, 2.0], [1.0, 2.0, 1.0], [4.0, 3.0, 1.0], [5.0, 4.0, 5.0], [1.0, 4.0, 5.0], [3.0, 1.0, 1.0], [1.0, 5.0, 5.0], [1.0, 5.0, 3.0], [1.0, 2.0, 1.0], [1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [3.0, 3.0, 2.0], [1.0, 5.0, 3.0], [1.0, 2.0, 4.0], [1.0, 2.0, 4.0], [1.0, 1.0, 5.0], [2.0, 1.0, 1.0], [1.0, 3.0, 1.0], [1.0, 1.0, 1.0], [5.0, 5.0, 5.0], [1.0, 1.0, 3.0], [1.0, 4.0, 5.0], [3.0, 1.0, 2.0], [1.0, 5.0, 1.0], [2.0, 1.0, 2.0], [1.0, 2.0, 1.0], [1.0, 2.0, 1.0], [1.0, 1.0, 1.0], [1.0, 1.0, 2.0], [1.0, 2.0, 1.0], [1.0, 1.0, 1.0], [2.0, 2.0, 2.0], [2.0, 5.0, 5.0], [4.0, 2.0, 4.0], [1.0, 4.0, 2.0], [1.0, 1.0, 1.0], [3.0, 1.0, 5.0], [1.0, 3.0, 1.0], [1.0, 2.0, 4.0], [1.0, 1.0, 1.0], [3.0, 3.0, 3.0], [2.0, 1.0, 4.0], [2.0, 1.0, 3.0], [1.0, 4.0, 2.0], [1.0, 3.0, 4.0], [1.0, 1.0, 1.0], [5.0, 5.0, 3.0], [2.0, 2.0, 5.0], [1.0, 2.0, 3.0], [1.0, 2.0, 1.0], [5.0, 3.0, 1.0], [1.0, 1.0, 1.0], [1.0, 3.0, 4.0], [1.0, 3.0, 1.0], [5.0, 5.0, 1.0], [1.0, 1.0, 1.0], [1.0, 2.0, 4.0], [1.0, 1.0, 3.0], [1.0, 3.0, 5.0], [1.0, 3.0, 1.0], [1.0, 1.0, 2.0], [1.0, 1.0, 3.0], [5.0, 4.0, 4.0], [1.0, 2.0, 2.0], [2.0, 5.0, 1.0], [1.0, 3.0, 5.0], [1.0, 5.0, 5.0], [1.0, 2.0, 1.0], [1.0, 1.0, 2.0], [5.0, 3.0, 4.0], [1.0, 1.0, 2.0], [5.0, 1.0, 5.0], [5.0, 4.0, 4.0], [1.0, 1.0, 5.0], [1.0, 1.0, 1.0], [2.0, 2.0, 4.0], [5.0, 2.0, 5.0], [2.0, 1.0, 1.0], [2.0, 2.0, 1.0], [1.0, 1.0, 4.0], [1.0, 1.0, 3.0], [1.0, 1.0, 1.0], [3.0, 1.0, 2.0], [2.0, 3.0, 3.0], [5.0, 1.0, 1.0], [1.0, 2.0, 1.0], [5.0, 1.0, 2.0], [1.0, 1.0, 3.0], [4.0, 2.0, 4.0], [1.0, 2.0, 1.0], [3.0, 1.0, 4.0], [1.0, 2.0, 3.0], [2.0, 1.0, 5.0], [1.0, 1.0, 2.0], [4.0, 3.0, 4.0], [3.0, 1.0, 3.0], [1.0, 5.0, 5.0], [5.0, 1.0, 1.0], [2.0, 1.0, 1.0], [5.0, 1.0, 5.0], [2.0, 1.0, 1.0], [1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [4.0, 1.0, 5.0], [3.0, 5.0, 5.0], [1.0, 2.0, 1.0], [2.0, 5.0, 3.0], [1.0, 2.0, 2.0], [1.0, 1.0, 3.0], [5.0, 1.0, 3.0], [3.0, 1.0, 2.0], [2.0, 4.0, 5.0], [2.0, 1.0, 1.0], [1.0, 3.0, 2.0], [1.0, 3.0, 4.0], [1.0, 1.0, 1.0], [2.0, 1.0, 2.0], [2.0, 1.0, 3.0], [1.0, 1.0, 1.0], [1.0, 1.0, 2.0], [5.0, 1.0, 3.0], [1.0, 2.0, 2.0], [1.0, 1.0, 5.0], [5.0, 1.0, 1.0], [2.0, 1.0, 1.0], [1.0, 1.0, 2.0], [1.0, 3.0, 5.0], [3.0, 5.0, 5.0], [3.0, 2.0, 3.0], [1.0, 5.0, 2.0], [1.0, 1.0, 1.0], [3.0, 2.0, 1.0], [5.0, 1.0, 1.0], [5.0, 1.0, 1.0], [2.0, 4.0, 5.0], [1.0, 4.0, 2.0], [2.0, 1.0, 3.0], [1.0, 2.0, 4.0], [5.0, 2.0, 2.0], [1.0, 1.0, 2.0], [1.0, 1.0, 1.0], [1.0, 3.0, 2.0], [1.0, 1.0, 2.0], [1.0, 1.0, 5.0], [1.0, 1.0, 1.0], [4.0, 5.0, 5.0], [3.0, 2.0, 2.0], [1.0, 1.0, 2.0], [3.0, 3.0, 2.0], [1.0, 4.0, 5.0], [1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [2.0, 2.0, 5.0], [1.0, 1.0, 1.0], [3.0, 5.0, 4.0], [1.0, 2.0, 1.0], [3.0, 1.0, 2.0], [1.0, 5.0, 5.0], [1.0, 1.0, 3.0], [3.0, 4.0, 2.0], [2.0, 5.0, 1.0], [5.0, 1.0, 3.0], [2.0, 2.0, 2.0], [1.0, 1.0, 1.0], [1.0, 1.0, 2.0], [1.0, 1.0, 5.0], [3.0, 1.0, 3.0], [1.0, 2.0, 3.0], [2.0, 5.0, 1.0], [1.0, 1.0, 1.0], [1.0, 1.0, 2.0], [2.0, 5.0, 4.0], [2.0, 5.0, 5.0], [1.0, 1.0, 1.0], [3.0, 2.0, 1.0], [1.0, 5.0, 5.0], [1.0, 2.0, 2.0], [1.0, 2.0, 2.0], [1.0, 1.0, 1.0], [2.0, 2.0, 2.0], [3.0, 4.0, 5.0], [2.0, 1.0, 5.0], [1.0, 2.0, 1.0], [1.0, 2.0, 5.0], [1.0, 1.0, 1.0], [3.0, 3.0, 2.0], [2.0, 3.0, 4.0], [1.0, 1.0, 3.0], [5.0, 1.0, 1.0], [2.0, 1.0, 1.0], [3.0, 4.0, 2.0], [1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [3.0, 2.0, 2.0], [1.0, 2.0, 4.0], [3.0, 3.0, 4.0], [1.0, 2.0, 2.0], [2.0, 1.0, 4.0], [1.0, 1.0, 2.0], [1.0, 1.0, 4.0], [1.0, 1.0, 2.0], [1.0, 1.0, 1.0], [1.0, 1.0, 1.0], [3.0, 2.0, 5.0], [1.0, 2.0, 2.0], [4.0, 4.0, 5.0], [1.0, 1.0, 2.0], [1.0, 1.0, 5.0], [3.0, 2.0, 1.0], [1.0, 1.0, 2.0], [1.0, 2.0, 2.0], [1.0, 2.0, 5.0], [1.0, 1.0, 2.0], [3.0, 4.0, 4.0], [1.0, 3.0, 2.0], [2.0, 1.0, 1.0], [5.0, 2.0, 2.0], [1.0, 2.0, 2.0], [3.0, 1.0, 4.0], [1.0, 2.0, 3.0], [5.0, 1.0, 3.0], [5.0, 1.0, 2.0], [1.0, 1.0, 4.0], [3.0, 5.0, 5.0], [5.0, 1.0, 4.0], [1.0, 2.0, 5.0], [3.0, 1.0, 1.0], [1.0, 1.0, 3.0], [1.0, 2.0, 4.0], [1.0, 3.0, 2.0], [1.0, 3.0, 3.0], [1.0, 1.0, 2.0], [4.0, 2.0, 1.0], [3.0, 1.0, 4.0], [1.0, 5.0, 5.0], [4.0, 1.0, 5.0], [1.0, 1.0, 1.0], [3.0, 1.0, 3.0], [1.0, 3.0, 1.0], [1.0, 1.0, 1.0], [2.0, 2.0, 3.0], [3.0, 1.0, 2.0], [3.0, 5.0, 2.0], [1.0, 3.0, 1.0], [1.0, 2.0, 5.0], [1.0, 1.0, 5.0], [3.0, 1.0, 2.0], [1.0, 5.0, 5.0], [2.0, 5.0, 5.0], [4.0, 5.0, 5.0], [2.0, 1.0, 1.0], [1.0, 1.0, 1.0], [1.0, 2.0, 2.0], [4.0, 5.0, 5.0], [3.0, 1.0, 1.0], [2.0, 1.0, 1.0], [1.0, 3.0, 2.0], [4.0, 2.0, 5.0], [5.0, 1.0, 1.0], [3.0, 5.0, 4.0], [1.0, 1.0, 2.0], [1.0, 3.0, 5.0], [1.0, 2.0, 3.0], [1.0, 1.0, 1.0], [3.0, 2.0, 4.0], [1.0, 3.0, 2.0], [1.0, 5.0, 5.0], [1.0, 2.0, 2.0], [2.0, 1.0, 2.0], [3.0, 1.0, 1.0], [1.0, 1.0, 2.0], [2.0, 3.0, 4.0], [1.0, 5.0, 2.0], [1.0, 1.0, 1.0], [1.0, 1.0, 5.0], [1.0, 1.0, 3.0], [2.0, 5.0, 1.0], [3.0, 5.0, 5.0], [3.0, 4.0, 2.0], [1.0, 2.0, 2.0], [3.0, 3.0, 3.0]]\n"
     ]
    }
   ],
   "source": [
    "UserRateID, SongRate = findMostSongUserID(data_sparse_arr, MostRateSongID)\n",
    "print('UserRateID:',UserRateID)\n",
    "print('SongRate:',SongRate)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 计算物品相似度度量"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 101,
   "metadata": {},
   "outputs": [],
   "source": [
    "def findSim(SongRate):\n",
    "    \n",
    "    SongListAverage = []\n",
    "    for i in range(1, len(SongRate)):\n",
    "        SongRateSum = 0\n",
    "        for j in range(len(SongRate[0])):\n",
    "            SongRateSum += SongRate[i][j]    \n",
    "        SongListAverage.append(SongRateSum / (len(SongRate[0])))\n",
    "    \n",
    "    #print('SongListAverage:', SongListAverage)\n",
    "    #print('SongListAverage len:', len(SongListAverage))\n",
    "    #print('')\n",
    "    \n",
    "    SongRateSubSongAverage = [] \n",
    "    SongListRateSubSongAverage = []\n",
    "    \n",
    "    for i in range(1, len(SongRate)):\n",
    "        SongRateSubSongAverage = []\n",
    "        for j in range(len(SongRate[0])):\n",
    "            SongRateSubSongAverage.append(SongRate[i][j] - SongListAverage[i - 1])\n",
    "        SongListRateSubSongAverage.append(SongRateSubSongAverage)    \n",
    "    \n",
    "    #print('SongListRateSubSongAverage:', SongListRateSubSongAverage)\n",
    "    #print('SongListRateSubSongAverage len:', len(SongListRateSubSongAverage))\n",
    "    #print('')\n",
    "     \n",
    "    MutilList = []\n",
    "    for i in range(len(SongListRateSubSongAverage)):\n",
    "        MutilList_1 = []\n",
    "        for j in range(len(SongListRateSubSongAverage[0]) - 1):\n",
    "            MutilList_1.append(SongListRateSubSongAverage[i][j] * SongListRateSubSongAverage[i][len(SongListRateSubSongAverage[0])-1])\n",
    "        MutilList.append(MutilList_1)\n",
    "    \n",
    "    #print('MutilList:', MutilList)\n",
    "    #print('MutilList len:', len(MutilList))\n",
    "    #print('')                             \n",
    "        \n",
    "    sumList1 = []  \n",
    "    for i in range(len(MutilList[0])):\n",
    "        Sum = 0\n",
    "        for j in range(len(MutilList)):\n",
    "            Sum += MutilList[j][i]   \n",
    "        sumList1.append(Sum)\n",
    "        \n",
    "    #print('sumList1:', sumList1)\n",
    "    #print('sumList1 len:', len(sumList1))\n",
    "    #print('')                            \n",
    "                                \n",
    "    MutilList2 = []\n",
    "    for i in range(len(SongListRateSubSongAverage)):\n",
    "        MutilList2_ = []\n",
    "        #print('SongListRateSubSongAverage[i]:', SongListRateSubSongAverage[i])\n",
    "        for j in range(len(SongListRateSubSongAverage[0])):\n",
    "            MutilList2_.append(pow(SongListRateSubSongAverage[i][j], 2))\n",
    "        MutilList2.append(MutilList2_)\n",
    "        \n",
    "    #print('') \n",
    "    #print('MutilList2:', MutilList2)\n",
    "    #print('MutilList2 len:', len(MutilList2[0]))\n",
    "    #print('')                            \n",
    "    \n",
    "    sumList2 = []  \n",
    "    for i in range(len(MutilList2[0])):\n",
    "        Sum = 0\n",
    "        for j in range(len(MutilList2)):\n",
    "            Sum += MutilList2[j][i]   \n",
    "        sumList2.append(Sum)\n",
    "        \n",
    "    #print('sumList2:', sumList2)\n",
    "    #print('sumList2 len:', len(sumList2))\n",
    "    #print('')    \n",
    "    \n",
    "    sumList3 = []\n",
    "    for i in range(len(sumList2)):\n",
    "        sumList3.append(math.sqrt(sumList2[i]))\n",
    "        \n",
    "    #print('sumList3:', sumList3)\n",
    "    #print('sumList3 len:', len(sumList3))\n",
    "    #print('')\n",
    "    \n",
    "    sumList4 = []\n",
    "    for i in range(len(sumList1)):\n",
    "        sumList4.append(sumList1[i] / (sumList3[i] * sumList3[len(sumList3)-1]))\n",
    "        \n",
    "    return sumList4    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 102,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sim: [-0.6139767121878018, -0.37549257254855894]\n"
     ]
    }
   ],
   "source": [
    "sim = findSim(SongRate)\n",
    "print('sim:', sim)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 预测最后一个歌曲的分数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 103,
   "metadata": {},
   "outputs": [],
   "source": [
    "def pred(SongRate, sim):\n",
    "    \n",
    "    maxSim = -10 \n",
    "    \n",
    "    simList = []\n",
    "    SongRateList = []\n",
    "    \n",
    "    for i in range(len(sim)-1):\n",
    "        if sim[i] > maxSim:\n",
    "            simList.append(sim[i])\n",
    "            SongRateList.append(SongRate[0][i])\n",
    "    \n",
    "    sum = 0\n",
    "    for i in range(len(simList)):\n",
    "        sum += simList[i] * SongRateList[i]\n",
    "    numerator = sum\n",
    "    #print('numerator:',numerator)\n",
    "    \n",
    "    sum = 0\n",
    "    for i in range(len(simList)):\n",
    "        sum += simList[i]\n",
    "    denominator = sum    \n",
    "    #print('denominator:',denominator)\n",
    "        \n",
    "    result = numerator / denominator\n",
    "    \n",
    "    return result"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 104,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SongRate predic: 5.0\n",
      "SongRate real: 1.0\n"
     ]
    }
   ],
   "source": [
    "rate = pred(SongRate, sim)\n",
    "#print('SongaAllRate:', SongRate[0])\n",
    "print('SongRate predic:', rate)\n",
    "print('SongRate real:', SongRate[0][2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
